#ifndef ICSP_FUNCTIONS
#define ICSP_FUNCTIONS

#include <SPI.h>

#if ARDUINO < 100
#include <WProgram.h>
#else  // ARDUINO
#include <Arduino.h>
#endif  // ARDUINO

#include <DigitalPin.h>

#include "controllerPins.h"

#define FUSE_PROT	0	/* memory protection */
#define FUSE_LOW	1	/* Low fuse */
#define FUSE_HIGH	2	/* High fuse */
#define FUSE_EXT	3	/* Extended fuse */

#define ICSP_EXTENDEDCOMMAND 0xAC
#define ICSP_PROGENABLE 0x53
#define ICSP_CHIPERASE 0x80
#define ICSP_RDYBSY 0xF0
#define ICSP_WRITELOCKBITS 0xE0
#define ICSP_WRITEFUSEBITSLOW 0xA0
#define ICSP_WRITEFUSEBITSHIGH 0xA8
#define ICSP_WRITEFUSEBITSEXT 0xA4
#define ICSP_READSIGNATURE 0x30
#define ICSP_LOADPROGMEMHIGH 0x48
#define ICSP_LOADPROGMEMLOW 0x40
#define ICSP_COMMITPROGMEM 0x4C


unsigned long ICSPCommand (uint8_t a, uint8_t b, uint8_t c, uint8_t d);
void programModeCommand();
void startProgramMode();
void endProgramMode();
uint16_t readSignature();
void programFuse (uint8_t fuse, uint8_t value);
void chipErase();
uint16_t pageAddress (uint16_t addr, uint8_t targetPageSize);
void programPage (uint8_t buff[], const uint16_t bufferSize, uint16_t startAddress, const uint8_t targetPageSize);
void commitPage (uint16_t address);
#endif
